/*
 * Operator.h
 *
 *  Created on: 18/06/2011
 *      Author: daniel
 */

#ifndef OPERATOR_H_
#define OPERATOR_H_

#include "Solution.h"
#include <vector>

class Operator {
public:

	/**
	 * Cruza dos soluciones con OX.
	 * @param: Dos soluciones.
	 * @return: Una solucion cruzada.
	 */
	static Solution *OX(Solution *a, Solution *b);

	/**
	 * Retorna un conjunto de movimientos 2-opt.
	 */
	static vector<int*> twoOptNeighborhood(Solution *s);

	/**
	 * Encuentra una vecindad para una solucion.
	 * @param: una solucion y un grado de variacion.
	 * @return: Una lista de intercambios que construyen
	 * 			la vecindad.
	 */
	static vector<int*> genericNeighbors(Solution *sact, int paso);

	/**
	 * Retorna una solucion nueva a partir de otra.
	 * @param: Una solucion.
	 * @return: Una solucion.
	 */
	static Solution *perturbation(Solution *s);

	/**
	 * Encuentra una vecindad para una solucion.
	 * @param: una solucion y un grado de variacion.
	 * @return: Un vector con los intercambios que
	 *          construyen la vecindad.
	 */
	static vector<int*> neighbors(Solution *sact, int paso);

	/**
	 * Retorna el mejor movimiento 2-Opt.
	 * @param: Una solucion.
	 * @return: int[2] a intercambiar.
	 */
	static int* twoOptMove(Solution *s);

	/**
	 * Retorna el mejor movimiento 3-Opt.
	 * @param: Una solucion.
	 * @return: int[2] a intercambiar.
	 */
	static vector<int*> threeOptNeighborhood(Solution *s);

	/**
	 * Retorna la solucion despues de aplicar el
	 * mejor movimiento 3-opt.
	 * @param: Una solucion mejorable.
	 * @return: Una solucion despues de aplicar
	 * 			el mejor movimiento 3-opt.
	 */
	static Solution *threeOptPerturbation(Solution *s);

	/**
	 *	Perturba una solucion aplicando swaps.
	 *	@param: Una solucion.
	 *	@return: Una solucion diferente a la que entro.
	 */
	static Solution *swapPerturbation(Solution *s);


	/**
	 * Perturba la solucion intercambiando arcos.
	 * @param: Una solucion y el grado de perturbacion que
	 * 		   se desea.
	 */
	static Solution *flipArcs(Solution *s, int step, int ini, int fin);


	/**
	 * Retorna la solucion despues de aplicar el
	 * mejor movimiento 3-opt.
	 * @param: Una solucion mejorable.
	 * @return: Una solucion despues de aplicar
	 * 			el mejor movimiento 3-opt.
	 */
	static vector<int*> threeOptMove(Solution *s);

};

#endif /* OPERATOR_H_ */
